package com.glory.hikvisionmobile.customView;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListPopupWindow;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;

import androidx.annotation.Nullable;

import com.glory.hikvisionmobile.R;

import java.util.ArrayList;
import java.util.List;


/**
 * *****************************
 *
 * @Anthor yazhou
 * @Email 1184545990@qq.com
 * @Time 2020/1/8 13:51
 * @DESC *****************************
 */
public class HikLabelSpinner2 extends LinearLayout {
    private static final String TAG = "HikLabelSpinner2";

    private boolean notnull;
    private String labelStr;
    private float labelSize;
    private int labelColor;
    private float labelContextSize;
    private int labelContextColor;
    private int labelWeight;
    private int labelContentWeight;
    private String labelContentHint;
    private int labelContentHintColor;

    private TextView label;
    private TextView labelContext;

    private SpinnerPopup mPopup;

    private OnItemSelectedListener mOnItemSelectedListener;
    private OnPopDismissListener mOnPopDismissListener;


    public HikLabelSpinner2(Context context) {
        super(context);
        init(context,null, 0, 0);
    }

    public HikLabelSpinner2(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context,attrs, 0, 0);
    }

    public HikLabelSpinner2(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context,attrs, defStyleAttr, 0);
    }

    public HikLabelSpinner2(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs, defStyleAttr, defStyleRes);
    }

    private void init(Context context, AttributeSet attrs, int defStyle, int defStyleRes) {
        if (attrs == null) {
            throw new IllegalArgumentException("must be init by xml");
        }
        TypedArray array = getContext().obtainStyledAttributes(attrs, R.styleable.HikLabelSpinner, defStyle, 0);
        notnull = array.getBoolean(R.styleable.HikLabelSpinner_notnull, false);
        labelStr = array.getString(R.styleable.HikLabelSpinner_label);
        if (labelStr == null) {
            labelStr = "Label";
        }
        labelSize = array.getDimension(R.styleable.HikLabelSpinner_labelSize, 24);
        labelColor = array.getColor(R.styleable.HikLabelSpinner_labelColor, Color.parseColor("#000000"));
        labelContextSize = array.getDimension(R.styleable.HikLabelSpinner_labelContentSize, 24);
        labelContextColor = array.getColor(R.styleable.HikLabelSpinner_labelContentColor, Color.parseColor("#000000"));
        labelWeight = array.getInt(R.styleable.HikLabelSpinner_labelWeight, 0);
        labelContentWeight = array.getInt(R.styleable.HikLabelSpinner_labelContentWeight, 0);
        labelContentHint = array.getString(R.styleable.HikLabelSpinner_labelContentHint);
        labelContentHintColor = array.getColor(R.styleable.HikLabelSpinner_labelContentHintColor, Color.parseColor("#999999"));
        array.recycle();

        inflate(context);
//        mPopup = new DropdownPopup(context, attrs, defStyle, defStyleRes);
        mPopup = new DropdownPopup2(context, labelContext);
    }

    private void inflate(Context context) {
        inflate(context, R.layout.hik_view_label_spinner2, this);

        label = findViewById(R.id.tv_label);
        labelContext = findViewById(R.id.spinner);

        if (notnull) {
            SpannableStringBuilder stringBuilder = new SpannableStringBuilder(labelStr + "*");
            ForegroundColorSpan span = new ForegroundColorSpan(Color.parseColor("#FF0000"));
            stringBuilder.setSpan(span, stringBuilder.length() - 1, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            label.setText(stringBuilder);
        } else {
            label.setText(labelStr);
        }
        label.setTextSize(TypedValue.COMPLEX_UNIT_PX, labelSize);
        label.setTextColor(labelColor);

        LayoutParams params1 = (LayoutParams) label.getLayoutParams();
        if (labelWeight > 0) {
            params1.weight = labelWeight;
        }
        label.setLayoutParams(params1);

        labelContext.setHint(labelContentHint);
        labelContext.setHintTextColor(labelContentHintColor);
        labelContext.setTextColor(labelContextColor);
        labelContext.setTextSize(TypedValue.COMPLEX_UNIT_PX, labelContextSize);
        LayoutParams params2 = (LayoutParams) labelContext.getLayoutParams();
        if (labelContentWeight > 0) {
            params2.weight = labelContentWeight;
        }
        labelContext.setLayoutParams(params2);

        labelContext.setOnClickListener(v -> {
            mPopup.show(getTextDirection(), getTextAlignment());
        });
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (mPopup != null && mPopup.isShowing()) {
            mPopup.dismiss();
        }
    }

    public TextView getLabelContext() {
        return labelContext;
    }

    public void setOnItemSelectedListener(OnItemSelectedListener onItemSelectedListener) {
        this.mOnItemSelectedListener = onItemSelectedListener;
    }

    public void setOnPopDismissListener(OnPopDismissListener onPopDismissListener) {
        this.mOnPopDismissListener = onPopDismissListener;
    }

    public void setAdapter(ListAdapter adapter) {
        this.mPopup.setAdapter(adapter);
    }

    public void setVerticalOffset(int px){
        mPopup.setVerticalOffset(px);
    }

    public void setHorizontalOffset(int px){
        mPopup.setHorizontalOffset(px);
    }


    //适配器
    public static abstract class HikSpinnerAdapter extends BaseAdapter{
        public abstract CharSequence getSelectedDesc(int position);
    }

    public static class HikSimpleSpinnerAdapter extends HikSpinnerAdapter{

        private List<Object> mData;

        public HikSimpleSpinnerAdapter(List<Object> mData) {
            this.mData = new ArrayList<>();
            if (mData != null) {
                this.mData.addAll(mData);
            }
        }

        public void setData(List data) {
            this.mData.clear();
            if (data != null) {
                this.mData.addAll(data);
            }
            notifyDataSetChanged();
        }

        @Override
        public CharSequence getSelectedDesc(int position) {
            return this.mData.get(position).toString();
        }

        @Override
        public int getCount() {
            return this.mData.size();
        }

        @Override
        public Object getItem(int position) {
            return this.mData.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null){
                convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.hik_item_spinner, parent, false);
            }
            ((TextView)convertView.findViewById(R.id.tv_label)).setText(mData.get(position).toString());
            return convertView;
        }

    }

    //弹框模型
    interface SpinnerPopup {
        void setAdapter(ListAdapter adapter);
        void show(int textDirection, int textAlignment);
        void dismiss();
        boolean isShowing();
        void setPromptText(CharSequence hintText);
        CharSequence getHintText();
        void setBackgroundDrawable(Drawable bg);
        void setVerticalOffset(int px);
        void setHorizontalOffset(int px);
        Drawable getBackground();
        int getVerticalOffset();
        int getHorizontalOffset();
    }

    //ListPopup实现
    class DropdownPopup extends ListPopupWindow implements SpinnerPopup {
        private CharSequence mHintText;
        private ListAdapter mAdapter;

        public DropdownPopup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
            setAnchorView(labelContext);
            setModal(true);
            setPromptPosition(POSITION_PROMPT_ABOVE);
            setOnItemClickListener((parent, view, position, id) -> {
                if (mOnItemSelectedListener != null) {
                    mOnItemSelectedListener.onItemSelected(view, position);
                }
                if (mAdapter instanceof HikSpinnerAdapter) {
                    labelContext.setText(((HikSpinnerAdapter) mAdapter).getSelectedDesc(position));
                }
                dismiss();
            });
        }

        @Override
        public void setAdapter(ListAdapter adapter) {
            super.setAdapter(adapter);
            mAdapter = adapter;
        }

        public CharSequence getHintText() {
            return mHintText;
        }

        public void setPromptText(CharSequence hintText) {
            mHintText = hintText;
        }

        void computeContentWidth() {
            setContentWidth(labelContext.getWidth());
        }

        public void show(int textDirection, int textAlignment) {
            boolean wasShowing = isShowing();

            computeContentWidth();

            setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
            super.show();
            ListView listView = getListView();
            listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
            listView.setTextDirection(textDirection);
            listView.setTextAlignment(textAlignment);

            if (wasShowing) {
                return;
            }

            ViewTreeObserver vto = getViewTreeObserver();
            if (vto != null) {
                ViewTreeObserver.OnGlobalLayoutListener layoutListener = () -> {
                    if (HikLabelSpinner2.this.getVisibility() != VISIBLE) {
                        dismiss();
                    } else {
                        computeContentWidth();
                        DropdownPopup.super.show();
                    }
                };
                vto.addOnGlobalLayoutListener(layoutListener);

                setOnDismissListener(() -> {
                    if (vto != null) {
                        vto.removeOnGlobalLayoutListener(layoutListener);
                    }
                    if (mOnPopDismissListener != null) {
                        mOnPopDismissListener.onDismiss();
                    }
                });
            }
        }
    }

    //普通Popup实现
    class DropdownPopup2 extends PopupWindow implements SpinnerPopup {

        private int mVerticalOffset;
        private int mHorizontalOffset;

        private CharSequence mHintText;

        private ListView mListView;
        private ListAdapter mAdapter;

        private View mAnchorView;

        public DropdownPopup2(Context context, View anchorView) {
            super(context);
            View contentView = LayoutInflater.from(context).inflate(R.layout.pop_list, null);
            setContentView(contentView);
            mListView = contentView.findViewById(R.id.listView);
            mAnchorView = anchorView;
            setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
            setFocusable(true);
            setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            setOutsideTouchable(true);
            setTouchable(true);

            mListView.setOnItemClickListener((parent, view, position, id) -> {
                if (mOnItemSelectedListener != null) {
                    mOnItemSelectedListener.onItemSelected(view, position);
                }
                if (mAdapter instanceof HikSpinnerAdapter) {
                    labelContext.setText(((HikSpinnerAdapter) mAdapter).getSelectedDesc(position));
                }
                dismiss();
            });
        }

        @Override
        public void setAdapter(ListAdapter adapter) {
            mAdapter = adapter;
            mListView.setAdapter(mAdapter);
        }

        private void computeContentWidth() {
            setWidth(mAnchorView.getWidth());
        }

        public void show(int textDirection, int textAlignment) {
            if (mAdapter == null || mAdapter.getCount() == 0) {
                return;
            }
            boolean wasShowing = isShowing();
            computeContentWidth();
            setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
            showAsDropDown(mAnchorView, mHorizontalOffset, mVerticalOffset);
            if (wasShowing) {
                return;
            }
            ViewTreeObserver vto = getViewTreeObserver();
            if (vto != null) {
                ViewTreeObserver.OnGlobalLayoutListener layoutListener = () -> {
                    if (HikLabelSpinner2.this.getVisibility() != VISIBLE) {
                        dismiss();
                    } else {
                        computeContentWidth();
                        showAsDropDown(mAnchorView, mHorizontalOffset, mVerticalOffset);
                    }
                };
                vto.addOnGlobalLayoutListener(layoutListener);

                setOnDismissListener(() -> {
                    if (vto != null) {
                        vto.removeOnGlobalLayoutListener(layoutListener);
                    }
                    if (mOnPopDismissListener != null) {
                        mOnPopDismissListener.onDismiss();
                    }
                });
            }
        }

        @Override
        public void setPromptText(CharSequence hintText) {

        }

        @Override
        public CharSequence getHintText() {
            return null;
        }

        @Override
        public void setVerticalOffset(int px) {
            mVerticalOffset = px;
        }

        @Override
        public void setHorizontalOffset(int px) {
            mHorizontalOffset = px;
        }

        @Override
        public int getVerticalOffset() {
            return mVerticalOffset;
        }

        @Override
        public int getHorizontalOffset() {
            return mHorizontalOffset;
        }
    }

    public interface OnItemSelectedListener{
        void onItemSelected(View view, int position);
    }

    public interface OnPopDismissListener{
        void onDismiss();
    }
}
